import { View, Dimensions, Platform, Image, ScrollView } from 'react-native'
import React, { Component, use, useEffect, useRef, useState } from 'react'
import { router, Stack, useLocalSearchParams, useRouter } from 'expo-router'
import { IconButton, Text, Button, Snackbar, Checkbox, Switch } from 'react-native-paper';
import { CameraView, CameraType, useCameraPermissions, Camera } from 'expo-camera';
import { useAudioPlayer, AudioPlayer } from 'expo-audio';
import * as ImagePicker from 'expo-image-picker';
import { atomWithStorage, useAtomCallback } from 'jotai/utils';
import { atom, useAtom, useSetAtom } from 'jotai';
import { Ionicons } from '@expo/vector-icons';
import ScanIcon from '@/components/ScanIcon';
import Animated, { BounceInDown, BounceOutDown, Easing, FadeIn, FadeOut, FlipInEasyX, FlipInEasyY, FlipInXUp, FlipOutEasyY, FlipOutXDown, FlipOutXUp, SlideInDown, SlideInUp, SlideOutDown, useSharedValue, withDecay, withRepeat, withSequence, withSpring, withTiming } from 'react-native-reanimated';
import { Canvas, DiffRect, rect, rrect } from '@shopify/react-native-skia';
import Toast from 'react-native-simple-toast';
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
import { continuouslyScanAtom, DevSpec, PickFunDeviceModel, PickFunVersion, scannedDevSpecAtom, soundAlertAtom } from '../store';
import { SystemBars } from 'react-native-edge-to-edge';
import { controlEdgeToEdgeValues, isEdgeToEdge } from 'react-native-is-edge-to-edge'
import { getDevSpecDescription, parseQrCodeString } from '@/utils';
import SwitchItem from '@/components/SwitchItem';

const chinaP0Audio = require('@/assets/audios/china_p0.mp3');
const chinaP1Audio = require('@/assets/audios/china_p1.mp3');
const globalP0Audio = require('@/assets/audios/global_p0.mp3');
const globalP1Audio = require('@/assets/audios/global_p1.mp3');


const Qrscan = () => {
    const [permission, requestPermission] = useCameraPermissions();
    const scale = useSharedValue(0.9);
    const [scanIconVisible, setScanIconVisible] = useState(true);
    const { width, height } = Dimensions.get("screen");
    const focusRectSize = 250;
    const outer = rrect(rect(0, 0, width, height), 0, 0);
    const inner = rrect(rect((width - focusRectSize) / 2, (height - focusRectSize) / 3, focusRectSize, focusRectSize), 0, 0);
    const [visible, setVisible] = useState(false);
    const [image, setImage] = useState<string | null>(null);
    const [scannedQr, setScannedQr] = useAtom(scannedDevSpecAtom);
    const { top, bottom } = useSafeAreaInsets();
    const [continuouslyScan, setContinuouslyScan] = useAtom(continuouslyScanAtom);
    const [soundAlert, setSoundAlert] = useAtom(soundAlertAtom);
    const [devSpec, setDevSpec] = useState<DevSpec | null>(null);
    const EDGE_TO_EDGE = isEdgeToEdge();
    const lastQrString = useRef<string | null>(null);
    const [showQrCodeIndicator, setShowQrCodeIndicator] = useState(false);
    //if use torch
    const [torch, setTorch] = useState(false);

    const audioPlayerMap: Record<string, AudioPlayer> = {
        [`${PickFunVersion.china}_${PickFunDeviceModel.p0}`]: useAudioPlayer(chinaP0Audio),
        [`${PickFunVersion.china}_${PickFunDeviceModel.p1}`]: useAudioPlayer(chinaP1Audio),
        [`${PickFunVersion.oversea}_${PickFunDeviceModel.p0}`]: useAudioPlayer(globalP0Audio),
        [`${PickFunVersion.oversea}_${PickFunDeviceModel.p1}`]: useAudioPlayer(globalP1Audio),
    };


    //hide qrcode indicator after 3 seconds
    useEffect(() => {
        const timer1 = setTimeout(() => {
            setShowQrCodeIndicator(true);
        }, 500);
        const timer2 = setTimeout(() => {
            setShowQrCodeIndicator(false);
        }, 5000);
        return () => { clearTimeout(timer1); clearTimeout(timer2); }
    }, []);


    // controlEdgeToEdgeValues({
    //     statusBarTranslucent: true,
    //     navigationBarTranslucent: true
    // });

    useEffect(() => {
        scale.value = withRepeat(
            withSequence(
                withTiming(0.8, { duration: 600, easing: Easing.inOut(Easing.quad) }),
                withTiming(0.9, { duration: 600 })
            )
            , -1, true);
    }, []);

    async function playAudioForDevSpec(devSpec: DevSpec) {
        const audioPlayer = audioPlayerMap[`${devSpec.ver}_${devSpec.model}`];
        if (audioPlayer) {
            audioPlayer.seekTo(0);
            audioPlayer.play();
        }
    }

    const pickImage = async () => {
        let result = await ImagePicker.launchImageLibraryAsync({
            mediaTypes: 'images',
            allowsEditing: false,
            aspect: [4, 3],
            quality: 1,
        });

        if (!result.canceled) {
            const selectedImageUri = result.assets[0].uri;
            setImage(selectedImageUri);
        }
    };

    const scanQRCodeFromImage = async () => {
        try {
            const qr = await Camera.scanFromURLAsync(
                image!
            );
            if (qr.length > 0) {
                let spec = parseQrCodeString(qr[0].data);
                if (spec) {
                    setScannedQr(spec);
                    router.back();
                } else {
                    Toast.showWithGravity('无法识别该二维码', Toast.LONG, Toast.CENTER);
                }
            } else {
                Toast.showWithGravity('未检测到二维码', Toast.LONG, Toast.CENTER);
            }
        } catch (e) {
            Toast.showWithGravity(`发生错误${e}`, Toast.LONG, Toast.CENTER);
        }
    }

    let cameraView;

    if (!permission) {
        cameraView = <View />;
    } else if (!permission.granted) {
        cameraView = <View className='items-center justify-center flex-1'>
            <Text variant='titleLarge' className='m-4'>需要访问您的摄像头，以便您能够扫描识别皮克方二维码。</Text>
            <Button mode='contained' className='mt-8' onPress={requestPermission}>继续</Button>
        </View>;
    } else {
        cameraView = <CameraView
            enableTorch={torch}
            barcodeScannerSettings={{ barcodeTypes: ['qr'] }}
            onBarcodeScanned={async (e) => {
                let spec = parseQrCodeString(e.data);
                if (!spec) {
                    Toast.showWithGravity('无法识别二维码', Toast.SHORT, Toast.CENTER);
                    return;
                }
                if (!continuouslyScan) {
                    setScannedQr(spec);
                    router.back();
                } else {
                    if (lastQrString.current === e.data) {
                        return;
                    }
                    lastQrString.current = e.data;
                    setDevSpec(spec);
                    if (soundAlert && spec) {
                        await playAudioForDevSpec(spec);
                    }
                }
            }}
            className='flex-1'
            facing={'back'}>
            <SystemBars style="light" />
            <Canvas style={{ flex: 1 }}>
                <DiffRect inner={inner} outer={outer} color="black" opacity={0.5} />
            </Canvas>

            <View className='absolute left-0 right-0 z-10 flex-row items-center justify-center' style={{ top: top + 16 }}>
                <Text className='p-4 text-xl text-white rounded-2xl bg-black/40'>
                    {continuouslyScan && devSpec ? getDevSpecDescription(devSpec) : '扫描皮克方二维码'}
                </Text>
            </View>

            <View className='absolute bottom-0 left-0 right-0 z-10 flex flex-col px-8' style={{ bottom: bottom + 32 }}>
                {showQrCodeIndicator &&
                    <Animated.View
                        entering={FlipInEasyX}
                        className='flex items-center justify-between mb-2'>
                        <Image
                            source={require('@/assets/images/qrcode-location.png')}
                            className='w-[100px] h-[100px]' />
                        <Text className='text-white' variant='bodyMedium'>二维码通常位于设备的底部</Text>
                    </Animated.View>}
                <View className='flex flex-row justify-between mb-4 bg-black/40 rounded-2xl'>
                    {Platform.OS === 'ios'
                        ?
                        <SwitchItem
                            text='连续扫描'
                            value={continuouslyScan}
                            onValueChange={() => setContinuouslyScan(!continuouslyScan)}
                        />
                        :
                        <Checkbox.Item
                            label='连续扫描'
                            labelStyle={{ color: 'white' }}
                            color='white'
                            uncheckedColor='white'
                            status={continuouslyScan ? 'checked' : 'unchecked'}
                            onPress={() => {
                                setContinuouslyScan(!continuouslyScan);
                            }}
                        />}
                    {Platform.OS === 'ios'
                        ?
                        <SwitchItem
                            text='语音播报'
                            value={soundAlert}
                            onValueChange={() => setSoundAlert(!soundAlert)}
                        />
                        :
                        <Checkbox.Item
                            label='语音播报'
                            labelStyle={{ color: 'white' }}
                            color='white'
                            uncheckedColor='white'
                            status={soundAlert ? 'checked' : 'unchecked'}
                            onPress={() => {
                                setSoundAlert(!soundAlert);
                            }}
                        />}
                </View>
                <View className='flex flex-row justify-between' >
                    <IconButton
                        className='bg-gray-800/70'
                        icon={torch ? 'lightbulb-outline' : 'lightbulb-off-outline'}
                        iconColor='white'
                        size={40}
                        onPress={() => setTorch(!torch)}
                    />
                    <IconButton
                        className='bg-gray-800/70'
                        icon="image"
                        iconColor='white'
                        size={40}
                        onPress={pickImage}
                    />
                    <IconButton
                        className='bg-gray-800/70'
                        icon="close"
                        iconColor='white'
                        size={40}
                        onPress={() => router.back()}
                    />
                </View>
            </View>

        </CameraView>
    }

    let imageView = <View className='items-center justify-start flex-1 w-full' style={{ paddingTop: top + 16 }}>
        <SystemBars style="auto" />
        <Image source={{ uri: image! }} className='w-full h-1/2' resizeMode='contain' />
        <View className='self-stretch px-4 pt-2 gap-y-4'>
            <Button className='w-full' onPress={pickImage} icon="refresh" mode='outlined'>重新选择</Button>
            <View className='flex flex-row gap-x-4'>
                <Button onPress={scanQRCodeFromImage} className='w-1/2 shrink' mode='contained'>确定</Button>
                <Button onPress={() => setImage(null)} className='w-1/2 shrink' mode='outlined'>取消</Button>
            </View>
        </View>
    </View>;

    function onDismissSnackBar(): void {
        setVisible(false);
    }

    return (
        <View className='flex-1'>

            <Stack.Screen options={{ headerShown: false }} />
            {image ? imageView : cameraView}
            <Snackbar
                visible={visible}
                onDismiss={onDismissSnackBar}
            >
                未检测到二维码
            </Snackbar>
        </View>
    )

}

export default Qrscan